package com.zhuhjay.handler;

import com.zhuhjay.model.domain.HttpResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * @author ZhuHJay
 * @date 2023/4/25 22:38
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.zhuhjay")
public class GlobalExceptionHandler {

    // -----        系统异常        -----

    /** 用于捕获@RequestBody类型参数触发校验规则抛出的异常 **/
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public HttpResult<?> handle(MethodArgumentNotValidException e) {
        StringBuilder sb = new StringBuilder();
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        for (ObjectError error : allErrors) {
            sb.append(error.getDefaultMessage()).append(";");
        }
        return HttpResult.fail(sb.toString());
    }

    /** 用于捕获@RequestParam/@PathVariable参数触发校验规则抛出的异常 **/
    @ExceptionHandler(value = ConstraintViolationException.class)
    public HttpResult<?> handle(ConstraintViolationException e) {
        StringBuilder sb = new StringBuilder();
        Set<ConstraintViolation<?>> conSet = e.getConstraintViolations();
        for (ConstraintViolation<?> con : conSet) {
            String message = con.getMessage();
            sb.append(message).append(";");
        }
        return HttpResult.fail(sb.toString());
    }

    /** 请求媒体类型不受支持 **/
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public HttpResult<?> handle(HttpMediaTypeNotSupportedException e) {
        return HttpResult.fail("请求媒体类型不支持");
    }

    /** 请求方式不支持 **/
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public HttpResult<?> handle(HttpRequestMethodNotSupportedException e) {
        return HttpResult.fail(e.getMessage());
    }

    // -----        自定义异常       -----

    /** 自定义异常，统一收集 **/
    @ExceptionHandler({RuntimeException.class})
    public HttpResult<?> handle(RuntimeException e) {
        return HttpResult.fail(e.getMessage());
    }

    // -----        未知异常        -----

    @ExceptionHandler(Exception.class)
    public HttpResult<?> handle(Exception e) {
        log.error("未察觉的服务器异常", e);
        return HttpResult.fail("服务器错误");
    }

}
